<template>
  <article class="page page-live-downloader">
    <h4 class="text-center">直播视频下载</h4>
    <div class="page-body row">
      <div class="col-4">
        <fieldset>
          <legend>参数配置</legend>
          <div class="fieldset-content">
            <div class="main">
              <div class="row-flex" align="center">
                <div class="row-flex-prefix">直播地址</div>
                <div class="row-flex-main"><input class="form-control" type="text" v-model.trim="videoUrl"
                    placeholder="请输入直播地址" /></div>
              </div>
              <div class="row-flex" align="center">
                <div class="row-flex-prefix">下载目录</div>
                <div class="row-flex-main"><input class="form-control" type="text" v-model="toPath" /></div>
                <div class="row-flex-suffix"><x-button @click="setToPath">选择</x-button></div>
              </div>
              <div class="row-flex" align="center">
                <div class="row-flex-prefix">保存频率</div>
                <div class="row-flex-main">
                  <div class="input-group">
                    <input class="form-control" type="number" v-model.trim="interval" min="1" max="60"
                      placeholder="间隔多久保存一次数据" />
                    <div class="input-group-append">
                      <span class="input-group-text">分钟</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="bottom">
              <x-button type="primary" block @click="clickHandler">{{ downloading > 0 ? '结 束' : '开 始'}}</x-button>
            </div>
          </div>
        </fieldset>
      </div>
      <div class="col-8">
        <fieldset>
          <legend>播放区域</legend>
          <div class="fieldset-content">
            <iframe :src="iframeUrl"></iframe>
          </div>
        </fieldset>
      </div>
    </div>
  </article>
</template>

<script>
const path = global.require('path')
const { remote } = global.require('electron')
const { dialog, session } = remote
const selfWindow = remote.getCurrentWindow()

export default {
  name: 'live-downloader',
  data() {
    return {
      videoUrl: '',
      iframeUrl: '',
      interval: 10,
      timer: null,
      dataList: [],
      downloadDict: {},
      tsIndex: 0,
      toPath: this.$sharedObject('desktopPath'),
      downloading: 0,
      loadingCount: 0
    }
  },
  methods: {
    // 设置下载目录
    setToPath() {
      let filePaths = dialog.showOpenDialogSync(selfWindow, {
        title: '选择目录',
        buttonLabel: '确定',
        defaultPath: this.$sharedObject('desktopPath'),
        properties: ['openDirectory']
      })
      if (filePaths instanceof Array && filePaths.length > 0) {
        this.toPath = filePaths[0]
      }
    },
    // 点击按钮
    clickHandler() {
      if (this.downloading > 0) {
        this.downloadStop()
      } else {
        this.downloadStart()
      }
    },
    // 开始下载
    downloadStart() {
      if (!this.videoUrl) {
        this.$toast('请输入视频地址')
        return
      }
      this.iframeUrl = ''
      this.$nextTick(() => {
        clearInterval(this.timer)
        this.iframeUrl = this.videoUrl
        let interval = Math.max(Math.min(parseFloat(this.interval) || 0, 60), 1)
        this.getDataStart()
        this.timer = setInterval(() => { this.saveDataList() }, interval * 60000)
        this.downloading = 1
      })
    },
    // 结束下载
    downloadStop() {
      clearInterval(this.timer)
      this.downloading = 0
      this.iframeUrl = ''
      this.$nextTick(() => {
        this.getDataStop()
        this.saveDataList()
      })
    },
    // 开始拦截数据
    getDataStart() {
      this.tsIndex = 0
      let filters = { urls: ['*://*/*'] }
      session.defaultSession.webRequest.onCompleted(filters, (details) => {
        let baseUrl = details.url.split('?')[0]
        if (/\.ts$/.test(baseUrl) && !this.downloadDict[baseUrl]) {
          let index = this.tsIndex
          this.tsIndex++
          this.downloadDict[baseUrl] = 1
          fetch(details.url, { method: 'get', responseType: 'arraybuffer' }).then(res => {
            return res.arrayBuffer()
          }).then((ab) => {
            this.dataList[index] = ab
          })
        }
      })
    },
    // 停止拦截数据
    getDataStop() {
      let filters = { urls: ['*://*/*'] }
      session.defaultSession.webRequest.onCompleted(filters, () => {
      })
    },
    // 将数据输出到本地
    saveDataList() {
      if (this.dataList.length === 0) return
      let filePath = path.join(this.toPath, `${Date.now()}.mp4`)
      let dataList = [...this.dataList]
      this.dataList = []
      dataList = dataList.filter(v => v).map(v => Buffer.from(v))
      let data = Buffer.concat(dataList)
      this.$sharedObject('jstoolsNode').writeFile(filePath, data).then(() => {
        this.$toast('保存成功')
      }).catch((err) => {
        this.$toast('保存失败' + err)
      })
    }
  }
}
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";

.page-live-downloader {
  display: flex;
  flex-direction: column;

  .row-flex {
    &+.row-flex {
      margin-top: 1em;
    }

    .row-flex-prefix {
      min-width: 5em;
      text-align: right;
    }

    .row-flex-main {
      text-align: left;
    }
  }

  .page-body {
    height: 0;
    flex-grow: 1;
    overflow: hidden;
    position: relative;

    fieldset {
      height: 100%;
    }

    .fieldset-content {
      height: calc(100% - 2em);
      display: flex;
      flex-direction: column;

      .main {
        height: 0;
        flex-grow: 1;
        overflow: hidden auto;
      }

      .bottom {
        .x-button {
          margin-top: .5em;
        }
      }

      iframe {
        display: block;
        width: 100%;
        height: 100%;
        background-color: #f5f5f5;
      }
    }
  }
}
</style>
